﻿namespace Leetcode.N0468;
public class Solution
{
    public string ValidIPAddress(string queryIP)
    {
        if (queryIP.IndexOf('.') > 0)
        {
            if (this.IsIpV4(queryIP))
            {
                return "IPv4";
            }
        }
        else if (queryIP.IndexOf(':') > 0)
        {
            if (this.IsIpV6(queryIP))
            {
                return "IPv6";
            }

        }
        return "Neither";
    }

    private bool IsIpV4(string ip)
    {
        var items = ip.Split('.');
        if (items.Length == 4)
        {
            for (int i = 0; i < items.Length; i++)
            {
                if (!this.IsIpV4Segment(items[i]))
                {
                    return false;
                }
            }
        }
        else
        {
            return false;
        }
        return true;
    }
    private bool IsIpV4Segment(string segment)
    {
        if (segment.Length > 3)
        {
            return false;
        }

        if ((segment.Length == 3 || segment.Length == 2) && segment[0] == '0')
        {
            return false;
        }

        if (int.TryParse(segment, out var val))
        {
            return val >= 0 && val <= 255;
        }

        return false;
    }

    private bool IsIpV6(string ip)
    {
        var items = ip.Split(':');
        if (items.Length == 8)
        {
            for (int i = 0; i < items.Length; i++)
            {
                if (!this.IsIpV6Segment(items[i]))
                {
                    return false;
                }
            }
        }
        else
        {
            return false;
        }
        return true;
    }

    private bool IsIpV6Segment(string segment)
    {
        if (segment.Length < 1 || segment.Length > 4)
        {
            return false;
        }


        foreach (var item in segment)
        {
            if ((item >= '0' && item <= '9') || (item >= 'a' && item <= 'f') || (item >= 'A' && item <= 'F'))
            {
                continue;
            }
            return false;
        }
        return true;
    }
}